package com.dji.compose_learning.sample

import kotlin.properties.Delegates
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/**
 * kotlin委托理解
 */

// 1.kotlin中默认get、set方法的使用
class Person1 {
    var name: String = "null"
        get() = "my name is :$field"
        set(value) {
            if (value.isNotBlank()) {
                field = value
            }
        }
}

// 2.对于上面的类定义如果所有类的属性字段set
// 都需要进行isNotBlank的判定那么书写起来会
// 很麻烦，每个属性字段都需要写一个set，如下：
class Person2 {
    var name: String = "null"
        get() = "my name is :$field"
        set(value) {
            if (value.isNotBlank()) {
                field = value
            }
        }
    var sex: String = "男"
        set(value) {
            if (value.isNotBlank()) {
                field = value
            }
        }
}

// 3.如果set赋值时需要做同样的逻辑处理我们可以通过委托来实现
class Person3 {
    var name: String by NotBlankDelegate("James")
    var sex: String by NotBlankDelegate("")
}

//自定义委托
class NotBlankDelegate(var value: String) : ReadWriteProperty<Any?, String> {
    override fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "my ${property.name} is:$value"
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        if (value.isNotBlank()) {
            this.value = value
        } else {
            this.value = "blank"
        }
    }
}

// 4.除了自定义委托还有一些可用的预定义的委托
class Person4 {
    var name: String by Delegates.notNull()
    var sex: String by Delegates.notNull()
    var age: Int by Delegates.vetoable(5) { property, oldValue, newValue ->
        newValue < 20  //新值小于20时赋值，否则不赋值
    }
    var grade:Int by Delegates.observable(1){property, oldValue, newValue ->
        if (newValue in 7..9) {
            educationInfo = "初中"
        }
        if (newValue <= 6) {
            educationInfo = "小学"
        }
        if (newValue in 10..12) {
            educationInfo = "高中"
        }
        if (newValue > 12) {
            educationInfo = "大学"
        }
    }
    var educationInfo:String = ""
}

// 5.延迟加载,lazy只实现了getValue 所以要求属性必须为val只读属性
// 采用lazy懒加载的属性其实是单例模式
class Person5 {
    val name by lazy { loadInfo()  }

    fun loadInfo():String {
        return "Lazy name"
    }
}

// 6.类委托的实现
interface DBOperation {
    fun add()
    fun delete()
    fun update()
    fun query()
}

class CommonOperation:DBOperation {
    override fun add() {
        println("Common add")
    }

    override fun delete() {
        println("Common delete")
    }

    override fun update() {
        println("Common update")
    }

    override fun query() {
        println("Common query")
    }
}

//这里MyOperation就不需要实现接口的所有方法了，交给委托common实现
//并且可以覆盖委托类实现的部分方法
class MyOperation(private val common:CommonOperation):DBOperation by common {
    override fun add() {
        println("MyOperation add")
    }
}
//或者这么写
class MyOperation1:DBOperation by CommonOperation() {
    override fun delete() {
        println("MyOperation1 delete")
    }
}


class KotlinDelegateSample {
//    fun main(args:Array<String>) {
//
//    }

    lateinit var name:String

    fun fu() {
        name = "ff"
        println(name)
    }

    fun testSample() {
        val person = Person3()
        println(person.name)
        println(person.sex)
    }
}